home *** CD-ROM | disk | FTP | other *** search
- Path: news.larc.nasa.gov!amiga-request
- From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v91i095: CpuBlit 1.0 - speeds up blitter on a 68020/30 Amiga, Part01/02
- Reply-To: ecarroll%maths.tcd.ie@pucc.PRINCETON.EDU
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v91i095@ab20.larc.nasa.gov>
- Date: 07 May 91 23:45:27 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga.misc
-
- Submitted-by: ecarroll%maths.tcd.ie@pucc.PRINCETON.EDU
- Posting-number: Volume 91, Issue 095
- Archive-name: utilities/cpublit-1.0/part01
-
- [ includes uuencoded executable and icons ...tad ]
-
- CpuBlit replaces the system BltBitMap routine with a version that uses your
- 68020/68030 when it is worthwhile to do so. This results in text scrolling
- twice as fast as usual, and in addition, the "colour flicker" effect normally
- present when scrolling multi-coloured text is removed.
-
- One advantage of the blitter is that while it is busy manipulating bitmaps,
- the CPU can be getting on with some other work. To facilitate this, you can
- tell CpuBlit to only use the CPU for blitting when it would otherwise be idle
- (i.e. no tasks are ready to run). This way, you get increased speed without
- affecting your Amiga's overall computing performance.
-
- If your Amiga only has a 68000, CpuBlit probably won't be of much use other
- than as a curiosity since the 68000 is slower than the blitter.
-
- This is V1.0, which fixes all known bugs in earlier versions available from
- ab20.larc.nasa.gov and bix.
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: CpuBlit.doc CpuBlit.uu CpuBlit0.uu History Kill_CpuBli.uu
- # src src/cpublit.c src/makefile src/res.s src/scroll.h src/small.a
- # src/system.h
- # Wrapped by tadguy@ab20 on Tue May 7 19:45:25 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'CpuBlit.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CpuBlit.doc'\"
- else
- echo shar: Extracting \"'CpuBlit.doc'\" \(14030 characters\)
- sed "s/^X//" >'CpuBlit.doc' <<'END_OF_FILE'
- X
- X CpuBlit V1.00 -- Uses CPU to perform blitter functions
- X
- X (c) Copyright Eddy Carroll, April 1991. Freely Distributable.
- X
- X
- XGETTING STARTED
- X
- X In brief, CpuBlit makes your 68020/68030-equipped Amiga scroll text
- X about twice as fast as before. You can quickly try it out as follows.
- X Run CpuBlit (make sure you have the cache enabled). Now try Typing a
- X file in a CLI window. Look at the speed. Change the text colour to
- X colour 3. Type the file again. Look at the lack of flicker on the text
- X as it scrolls. Nice, eh?
- X
- X If you have Workbench 2.0, you can install CpuBlit permanently by
- X simply dragging its icon into your WBStartup drawer. Otherwise, you
- X need to call CpuBlit from your Startup-Sequence. I recommend using the
- X -2 or -s options for general use, though you may like to experiment
- X with the others.
- X
- X Now read on for a more detailed description.
- X
- X
- XINTRODUCTION
- X
- X After upgrading from an A1000 to an A3000 a while ago, I was in Amiga
- X heaven. The display was great, the disk performance much improved, and
- X the speed awesome (at least compared to the A1000). But there was one
- X blemish on this otherwise perfect scene: the speed of text scrolling
- X in CLI windows. On a 704 x 560 screen, a snail wouldn't have much trouble
- X keeping up with a full size CLI window.
- X
- X Thus was born CpuBlit. It replaces the standard system BltBitMap routine
- X with a version that uses the 68030 where practical. The 68030 can
- X comfortably outrun the blitter for simple tasks like scrolling, although
- X the blitter still wins out if the data has to be bit shifted as well
- X (for example when scrolling sideways). Another benefit of using the CPU
- X is that it isn't constrained to operating on one bitplane at a time; it
- X can do them all simultaneously. So, the infamous "flicker" effect when
- X coloured text is scrolling disappears. This is particularly useful when
- X you're logged onto a bulletin board with colour ANSI menus.
- X
- X At this stage, I imagine some of you are getting ready to jump up and
- X complain about system throughput suffering, and how overall, the blitter
- X plus the CPU is faster than the CPU on its own. I certainly wouldn't
- X argue with that. So, CpuBlit can be setup to only use the CPU if no
- X other tasks are ready to use it. That way, you get improved performance
- X when you are single tasking, yet multiple tasks operate at full
- X efficiency.
- X
- X There is one caveat. CpuBlit will probably only be of use to you if you
- X have at least a 68020 installed in your Amiga; using the standard 68000
- X doesn't give any noticeable speed increase. In fact, even a standard
- X 68020 Amiga may not give much speed increase since it only has a 16 bit
- X datapath into chip RAM. The A3000 on the other hand can access chip ram
- X 32 bits at a time and CpuBlit takes advantage of this. The easiest way to
- X find out is to give it a try and see if you notice any other difference.
- X A3000 owners will certainly notice a difference -- an A3000-25 performs
- X blits about 2.8 times faster than the blitter, which results in text
- X scrolling at about twice the normal speed (actually displaying the text
- X to be scrolled takes a constant amount of time, regardless of what method
- X you use to scroll it).
- X
- X To get the best speed increase, use a non-overscanned screen of not
- X more than four colours, and ensure you have the CPU cache enabled (it
- X is disabled by default under Workbench 1.3 -- use SetCPU by Dave Haynie
- X to enable it). Both overscan and 8 or 16 colour screens will decrease
- X CpuBlit's efficiency, since the custom chips access CHIP ram more
- X frequently, leaving less time available for the CPU. Even with these
- X restrictions, you should still find CpuBlit about 50% faster than the
- X blitter on the A3000.
- X
- X
- XUSAGE
- X
- X You can start CpuBlit from either the CLI or the Workbench. There are
- X a number of parameters you can change, to alter CpuBlit's operation.
- X When you start CpuBlit, it automatically detaches itself from the CLI
- X window. Any combination of the following options can be given on the
- X command line or as Workbench ToolTypes. Note that each options has
- X two ways of specifying it. You can use whichever way you like best.
- X
- X BLITMODE=ALWAYS
- X -a
- X This is the default setting, so you normally don't need to give it
- X specifically. In this mode, CpuBlit always use the CPU where
- X possible. If you tend to only do one thing on your Amiga at a time,
- X this is probably the best option to use.
- X
- X BLITMODE=ONE
- X -1
- X In this mode, CpuBlit will only use the CPU for blits if there are
- X no other tasks ready to run at that time. The blitter is used at all
- X other times. Hence, you get fast blits whenever the CPU would be
- X otherwise idle, and normal processing speed when running multiple
- X tasks.
- X
- X There is one catch. When displaying text via the console device,
- X the program displaying the text is considered to be still running,
- X even though it's the console device that actually outputs the text.
- X For those interested, this is because the console device runs at
- X a higher priority than user applications and so preempts the task
- X before it has a chance to go to sleep. Hence, CpuBlit will think the
- X program is waiting to do work, and won't use the CPU for blitting.
- X
- X This means that the -1 option will only speed up scrolling when a
- X task scrolls the text directly, rather than indirectly via the
- X console device. Comms packages and text editors are the most likely
- X candidates for this. Standard CLI windows won't show any improvement.
- X
- X BLITMODE=2
- X -2
- X In this mode, CpuBlit will only use the CPU for blits if there is
- X at most one other task waiting to run. This results in everything
- X being speeded up (both applications and CLI output) but isn't quite
- X as system friendly as using -1. It should be more than adequate for
- X most people however.
- X
- X BROKEN=[YES|NO]
- X -b
- X Some programs don't initialise bitmap structures properly. By
- X default, CpuBlit passes such bitmaps on to the blitter and doesn't
- X attempt to handle them. Using this option tells CpuBlit to bypass the
- X validation checks it normally performs on bitmaps, and so may allow
- X broken programs like this to gain the benefits of faster blitting;
- X it may also cause problems. If you have a program that you think
- X should be sped up by CpuBlit and it seems to be showing no noticeable
- X change, then give this option a try; else, leave it alone.
- X
- X SINGLE=[YES|NO]
- X -o
- X This option tells CpuBlit to only handle blits where the source and
- X destination bitmaps are the same. Typically, this only happens when
- X a text window is scrolling. Normally you should not need to use this
- X option as CpuBlit should co-exist happily with every program that
- X uses the blitter. However, if CpuBlit seems to be incompatible with
- X some particular application, specifying `-o' will allow you to
- X continue using it. Don't forget to notify me about the problem, so
- X that it can be fixed!
- X
- X MINTASKPRI=N
- X -pN
- X If you like to keep a program running in the background (like a
- X Mandelbrot generator) then you may find it counteracts the -1 and -2
- X options (since it is always ready to run). You can tell CpuBlit
- X to ignore all such tasks using this option; any task with a priority
- X less than N will not be considered ready to run.
- X
- X Normally, CpuBlit will ignore any tasks with a priority less than
- X zero, which is perfectly adequate for most cases. You can override
- X this with a different setting if you like. For example, setting
- X MINTASKPRI=-5 will cause your Mandelbrot program at priority -1 to
- X be considered, but not your CPU monitor at priority -20.
- X
- X BLITMODE=SHARE
- X -s
- X In this mode, CpuBlit attempts to share blits between the CPU and the
- X blitter. The CPU will be used for blits by default, but if a task
- X tries to blit some data while another task is already using the CPU
- X to blit data, the blitter is used for the former. The result is
- X better overall throughput.
- X
- X If you try experimenting with two CLI windows to see this effect in
- X action, you won't notice anything; this is because the console.device
- X used for scrolling CLI windows is single threaded and waits for a
- X blit in one window to finish before starting another. Hence, both
- X windows are scrolled using the CPU. It works fine in the case of
- X a CLI window and a program that bypasses the console device (such as
- X a comms package).
- X
- X HELP
- X -h
- X Prints out a brief help message, listing the valid options. In fact,
- X giving any invalid option will cause this message to be printed.
- X
- X QUIT
- X -q
- X This option asks any copy of CpuBlit already installed to remove
- X itself. If another program has patched BltBitMap since CpuBlit was
- X started, you'll get a message asking you to terminate that program
- X and then try again.
- X
- X If you run CpuBlit with no options, it behaves as if you had typed:
- X
- X CPUBLIT BLITMODE=ALWAYS SINGLE=NO BROKEN=NO MINTASKPRI=0
- X
- X You can pick a different mode of operation at any time by simply running
- X CpuBlit again with new options; it's not necessary to remove the previous
- X copy first. You can use -a to cancel the effect of the -b and -o options.
- X Note that only one of -a, -1, -2 and -s can be in effect at a time. Also,
- X the BROKEN and SINGLE options default to YES if you use them without
- X specifying a YES/NO value.
- X
- X
- XWORKBENCH
- X
- X As mentioned above, CpuBlit can be started from Workbench. It doesn't
- X return to Workbench until it quits, so if you are starting it from your
- X WBStartup drawer (under 2.0) one of the tooltypes must be DONOTWAIT.
- X in the icon.
- X
- X When CpuBlit starts up, it parses all the ToolTypes in its own icon,
- X followed by the tooltypes in any project icons you specified. This
- X can be handy if you have several configurations of CpuBlit that you
- X like to switch between. Simply create a project icon for each one,
- X and set the appropriate tooltypes. Then set the default tool for each
- X icon to CpuBlit. Now, clicking on any of the icons will set the
- X corresponding CpuBlit options.
- X
- X To remove CpuBlit from Workbench, you need to start it from an icon
- X which has a QUIT tooltype. The standard CpuBlit distribution includes
- X such an icon that you can use. If CpuBlit cannot remove itself (perhaps
- X because someone else has patched into the BltBitMap routine ahead of
- X CpuBlit) then the screen will flash. You can type CpuBlit QUIT in
- X a CLI window for a more detailed explanation.
- X
- X
- XIMPLEMENTATION
- X
- X This section gives a brief description of how CpuBlit works. It's not
- X necessary to read this to use CpuBlit, it's included merely for those
- X interested.
- X
- X CpuBlit only handles blits with a very specific set of characteristics.
- X First of all, the source and destination bitmaps must be aligned on the
- X same bit boundary within a longword. For example, a blit from 0,0 to
- X 128,100 would be okay whereas a blit from 0,0 to 100,100 would fail.
- X In addition, only blitter functions of the form $Cx are supported
- X (i.e. plain replace operation). Also, the source and destination rows
- X must be different; if they are the same, a sideways blit is being
- X performed, and this is not supported.
- X
- X Assuming the blit fulfills all these criteria, CpuBlit then checks
- X system activity to see whether or not it is appropriate to use the
- X CPU at all. Exactly what is checked depends on the option selected
- X when CpuBlit was installed.
- X
- X Assuming everything is still okay, CpuBlit then works out how many
- X bitplanes there are in the bitmap, and calls one of four routines to
- X handle the actual scrolling. It also handles any bitplane pointers of
- X $FFFFFFFF or $00000000 at this time (new for Workbench 2.0, these
- X values are legal for bitplane pointers, and act as if they pointed to
- X either a solid or empty bitplane). If there are more than four
- X bitplanes, the blit is split into two operations; the first four planes
- X are moved, followed by the remaining planes. While this results in a
- X bit of colour flicker for deep bitmaps, it is still not as bad as when
- X the bitplanes are moved separately.
- X
- X The actual bitmap copying is done using optimised 68000 code. The bulk
- X of the data on each row is copied using a MOVE.L/DBF loop, and the uneven
- X bits at the sides are copied separately. No non-68000 instructions are
- X used (there wouldn't be any advantage to it anyway) so CpuBlit will still
- X run on a 68000 Amiga (not that there's much point). Due to a lack of
- X CPU registers (only 16 ... how DO people manage on Intel chips with a
- X mere 8 registers? :-) the routines for copying three and four bitplanes
- X aren't quite as efficient as those for copying one and two bitplanes.
- X However, they are still quite a bit faster than the blitter itself, and
- X the removal of colour flicker is more than worth the small loss in speed.
- X
- X
- XACKNOWLEDGEMENTS
- X
- X Thanks to Andy Mowatt for encouraging me to change CpuBlit from an idea
- X into a program. Thanks also to the following people who provided useful
- X feedback and bug reports for beta versions of CpuBlit: Steve Tibbett,
- X David Joiner, Mike Sinz, Dan Ten Ton, Robert Jenks, LeRoy Hutzenbiler,
- X Jim Biggs, Mike Meyer, Urban Mueller, Jamie Clark, Marc Jacobs and
- X Albert-Jan Brouwer. Their help is greatly appreciated.
- X
- X
- XAUTHOR
- X
- X Eddy Carroll
- X
- X Email: ecarroll@maths.tcd.ie
- X Phone: +353-1-287-4540
- X Snailmail: The Old Rectory, Delgany, Co. Wicklow, Ireland.
- X
- X
- XDISTRIBUTION
- X
- X CpuBlit may be freely distributed, as long as no charge is made other
- X than to cover time and copying costs. If you want to include CpuBlit
- X as part of a commercial package, contact the author listed above. Fred
- X Fish is specifically given permission to include CpuBlit in his fine
- X disk library.
- END_OF_FILE
- if test 14030 -ne `wc -c <'CpuBlit.doc'`; then
- echo shar: \"'CpuBlit.doc'\" unpacked with wrong size!
- fi
- # end of 'CpuBlit.doc'
- fi
- if test -f 'CpuBlit.uu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CpuBlit.uu'\"
- else
- echo shar: Extracting \"'CpuBlit.uu'\" \(10162 characters\)
- sed "s/^X//" >'CpuBlit.uu' <<'END_OF_FILE'
- Xbegin 666 CpuBlit
- XM```#\P`````````"``````````$```7&```!)@```^D```7&2.=^_DOO`#0D?
- XM2"0`2?D`````+'@`!"E.`!`I3P`8(`V0K0`$!H````"`*4``!$/L`"AP`$ZN1
- XM_=@I0``<9P`!%"9N`11*JP"L9AY!ZP!<3J[^@$'K`%Q.KOZ,*4``)"\`<``O/
- XM`&```,X@:P"LT<C1R")H`!#3R=/)(`)R`!(9*4D`(-"!4H!"9U*``D#__I_`V
- XM58!"=P@`(`)3@-2!'[(``"``4X)1R/_V(`)"-R``4X(?L2``(`!1RO_X0_<`@
- XM`21/G_P```&0)D\NBD7O``1T`6$T91)G^D'I__]A'&$H9OQ"*?__8.H@26$."
- XM81ID_$(I__]A$F;\9]@DR%)"#$(`9&,B<&Y@5!`99R8,```B9Q8,```@9PH,K
- XM```)9P0,```*`CP`'DYU`#P``0(\`/M.=2\++P)'^0``!%AR`"`\````$&`"I
- XM)L%1R/_\3KH')G``8`AP9&`$("\`!"\`+'@`!")L`!Q.KOYB2JP`)&<0+&P`9
- XM$$ZN_WPB;``D3J[^AB`?+FP`&$S??WY.=0``+P<N+P`(("P$B&<(+P!.NA1\^
- XM6$\O!TZZ_[)83RX?3G4M80``+3$``"TR```M<P``+6(``"UO```M<0``+7``>
- XM`$),251-3T1%``!!3%=!65,``$].10!45T\`4TA!4D4`0E)/2T5.``!.3P``.
- XM4TE.1TQ%``!-24Y405-+4%))``!154E4``!#<'5";&ET(%8Q+C`P`&=R87!H!
- XM:6-S+FQI8G)A<GD``$-P=4)L:70Z(&-O=6QD;B=T(&-R96%T92!L;V-A;"!M;
- XM97-S86=E('!O<G0N"@!I8V]N+FQI8G)A<GD``&EN='5I=&EO;BYL:6)R87)YG
- XM`$-P=4)L:70@<F5M;W9E9"!S=6-C97-S9G5L;'DN"@``0V]U;&1N)W0@<F5MF
- XM;W9E($-P=4)L:70[('-O;65O;F4@96QS92!H87,@<&%T8VAE9"!";'1":71-Z
- XM87`N(%!L96%S92!R96UO=F4*86YY(&]T:&5R('5T:6QI=&EE<R!Y;W4@:&%V3
- XM92!I;G-T86QL960@86YD('1H96X@=')Y(&%G86EN+@H``$-P=4)L:70@:&%S-
- XM;B=T(&)E96X@:6YS=&%L;&5D('EE="X*`$-O=6QD;B=T('-P87=N(&)A8VMGN
- XM<F]U;F0@0W!U0FQI="!T87-K+@H``$-P=4)L:70@5C$N,#`@J2`Q.3DQ($5DT
- XM9'D@0V%R<F]L;"X*`"\+)F\`""`3Y8!![`,B*7`(``-$*6L`!`-(*6L`"`-,[
- XM&6L`#`-0)E].=4Y5__A(YP`P)FT`"$AX``)(>OW6+PM.NA%<3^\`#$J`9A)P!
- XM`"E``S(I0`,V*4`#.F```L!(>``"2'K]LB\+3KH1-$_O``Q*@&8*<`$I0`,R5
- XM8``"H$AX``)(>OV6+PM.NA$43^\`#$J`9@IP`BE``S)@``*`2'@``DAZ_7HO@
- XM"TZZ$/1/[P`,2H!F"G`#*4`#,F```F!(>``"2'K]7B\+3KH0U$_O``Q*@&8*W
- XM<`$I0`,Z8``"0$AX``)(>OU"+PM.NA"T3^\`#$J`9@IP`2E``S9@``(@2'@`;
- XM`DAZ_28O"TZZ$)1/[P`,2H!F"G`!*4`$C&```@!(>``"2'K]"B\+3KH0=$_OL
- XM``Q*@&8:2BL``F<40>L``B\(3KH2#%A/&4`#/F```=!(>``(2'K\WB\+3KH0[
- XM1$_O``Q*@&8``)Q%ZP`(($I2BDH09P``B$H29P``@DAX``9(>OR\+PI.NA`8/
- XM3^\`#$J`9@A"K`,R8``!ADAX``-(>ORF+PI.N@_Z3^\`#$J`9@IP`2E``S)@P
- XM``%F2'@``TAZ_(HO"DZZ#]I/[P`,2H!F"G`"*4`#,F```49(>``%2'K\;B\*!
- XM3KH/ND_O``Q*@&8``2YP`RE``S)@``$D<`!@``$@2'@`!DAZ_$PO"TZZ#Y)/#
- XM[P`,2H!F1D'K``8O2``(*TC__%*(2.T!`/_\(&\`"$H09R!(>``"2'K\(B\M1
- XM__Q.N@]>3^\`#$J`9@A"K`,Z8```S'`!*4`#.F```,)(>``&2'K[_"\+3KH/2
- XM-D_O``Q*@&9"0>L`!B](``@K2/_\4HA([0$`__P@;P`(2A!G'DAX``)(>OO&7
- XM+RW__$ZZ#P)/[P`,2H!F!D*L`S9@<'`!*4`#-F!H2'@`"DAZ^ZPO"TZZ#MY/R
- XM[P`,2H!F,$'K``HO2``(*TC__%*(*TC__")O``A*$6<22A!G#B\(3KH08EA/:
- XM&4`#/F`F<`!@)$AX``1(>OMR+PM.N@Z83^\`#$J`9@AP`2E`!(Q@!'``8`)P!
- XM`4S?#`!.74YU2.<`,B9O`!`@;``0,"@`%'(DL$%E#")++'@`!$ZN_GI@."QXQ
- XM``1.KO]\(&P`$"1H`8@@"F<:("H`"F<0($`B2Q`8L!EF!DH`9O9G!"128.(L!
- XM>``$3J[_=B`*3-],`$YU3E7_\$CG`3)^`47Z!(Q"ITAZ^N!.N@\B4$\F0"`+!
- XM9P`!*D/Z^MQP`"QX``1.KOW8*4`$6$J`9P`!$B)`,'S_XDWZ!%P@#BQX``1.1
- XMKOY<)(`@2RQX``1.KOZ`($LL>``$3J[^C"E`!(1*@&<``*@@0"`H`!A*@&<,9
- XM4X!G'E.`9SI@``""<`U!(>OF`80#^*EA/)$`@"F=T<`$I0`24S
- XM0J="ITZZ#:Q03RE`!(AF+DJL!)!F'BQL`!Q.KO_$<BTO00`D(@!!^OED)`@F[
- XM+P`D3J[_T$AX``IA`/BL6$\I;`2(!')"K`1\0>P#,BE(!'@@2D/L!&0L>``$1
- XM3J[^DB!L!(A.KOZ`(&P$B$ZN_HQ*K`209P``LB!L`"0K:``D__1#^ODX<``L#
- XM>``$3J[]V"E`!&!F"DAX``5A`/A,6$]\`"!L`"2\J``<;&X@;?_T(!!G7B!H>
- XM``1*$&=6(@`L;``<3J[_@BH`(&W_]"!H``0L;`1@3J[_LBM`__!G'B!`*V@`?
- XM-O_L(&W_["`09PXO`&$`^BY83UBM_^Q@ZB!M__`L;`1@3J[_IB(%+&P`'$ZN'
- XM_X)2AE"M__1@B")L!&`L>``$3J[^8F!*?`&\AVQ$(`;E@"\S"`!A`/GH6$]*I
- XM@&8N+&P`'$ZN_\1![``T(DA*&6;\4XF3R"(`)@E![``T)`A.KO_02'@`!6$`=
- XM]WY83U*&8+A*K`249P``SDJL!(QG"'`"*4`$?&`&<`$I0`1\($I#[`1D+'@`$
- XM!$ZN_I(@;`2(3J[^@"!L!(A.KOZ,2JP$D&<L<`*PK`2`9B1#^O@.<`!.KOW8]
- XM*4`$7$J`9Q(L0)'(3J[_H").+'@`!$ZN_F)*K`209EIP`;"L!(!F("QL`!Q.#
- XMKO_$<AXO00`D(@!!^O?>)`@F+P`D3J[_T&`R<`*PK`2`9BHL;``<3J[_Q')#3
- XMTH$O00`D(@!!^O?4)`@F+P`D3J[_T$AX``5A`/:N6$]"IV$`]J983TJL!(QGJ
- XM+DJL!)!F'BQL`!Q.KO_$<B,O00`D(@!!^O@@)`@F+P`D3J[_T$AX``5A`/9R+
- XM6$](;`,R80#X=EA/2JP$D&<&80#[\&!B2'@/H$AZ^^9(>``%2'KVT$ZZ"5)/<
- XM[P`02H!F*"QL`!Q.KO_$<B@O00`D(@!!^O?J)`@F+P`D3J[_T$AX``IA`/88?
- XM6$\L;``<3J[_Q'(C+T$`)"(`0?KW["0()B\`)$ZN_]!"IV$`]?),[4SL_\!.B
- XM74YU```P'\V(S8A3N0```T`L'T[Y```+O$YU2D1G^K/(9@:V06?L8`A*N0``/
- XM`TAFXB\&`@8`\`P&`,!FU"P`M88"!@`?9LI*N0```TQF&$HH``1FO$IH``9F0
- XMMDHI``1FL$II``9FJE*Y```#0,V(('D```-$3M#-B"PY```#0&:*8%8@>0``I
- XM`!!!Z`&6L>@`"&=$/P`@4"!0$"@`"2!0S8A*AF<*L#D```-0;`#_6#`?8"8@V
- XM>0```!!!Z`&6L>@`"&<4(%`P:``(S8B\.0```U!L`/\X8`+-B$CG??Y.KO\<M
- XM2,!(P4C"2,-(Q$C%MD%B```P/"@``$C&)$;#QBP`YHX"!@#\TH8H03PI``!(_
- XMQB9&Q\8L`N:.`@8`_-:&*D-@.-*%4X$\*```2,;#QD2&)$8L`.:.`@8`_-*&<
- XM*$'6A5.#/"D``$C&Q\9$AB9&+`+FC@(&`/S6ABI#`D``']B`(@0"00`?ZHS2(
- XM@=*!9@)3A$WZ!P(D-A``T(#0@$WZ!G8B-@``?``<*``%O"D`!64$'"D`!5.
- XM(`12@-"`T("5P)?`Q4S'35.$)@0@!4'H``A#Z0`(*`@J"2XO`!1/[__`+$\_]
- XM!WX`XM=D+E)'($0B12@0*A%&A6<``*!&A6<``)I&A&<``)Q&A&<``*3)B,N),
- XMT<K3RRS(+,E8A%B%4<[_R%2/G<\L#N*.649J"$_O`$!@``"*#$8`#&(8)@-J>
- XM!L*"4$901BQ[:#).ED_O`$!@``!L)@-J",*"80`$MF`(80`"G`1&`!!/[P`@^
- XM+'MH#$Z63^\`(&```$8```Y.```.O@``#VX``!!^```1S@``$?H``!(V```2Z
- XMDLF(RXE@`/]ZR8C+B=/+80`$U&``_VS)B,N)T\MA``408`#_7B`'4[D```-`#
- XM3-]_OBP?3G5(Y__"3>\`,"!>(EY3@"@!1H0J`D:%4X-K```P+!C,@2X1SH2.N
- XMAB+'+`,BV%'.__PL&,R"+A'.A8Z&(L?1S-/-4<C_VDS?0_].=2P8S($N$<Z$4
- XMCH8BQRP8S((N$<Z%CH8BQ]',T\U1R/_B3-]#_TYU2.?_\DWO`#A,U@\`4X`H%
- XM`4:$*@)&A5.#:P``5"P8S($N$<Z$CH8BQRP:S($N$\Z$CH8FQRP#(MA1SO_\@
- XM+`,FVE'.__PL&,R"+A'.A8Z&(L<L&LR"+A/.A8Z&)L?1S-/-U<S7S5'(_[9,O
- XMWT__3G4L&,R!+A'.A(Z&(L<L&,R"+A'.A8Z&(L<L&LR!+A/.A(Z&)L<L&LR"K
- XM+A/.A8Z&)L?1S-/-U<S7S5'(_\9,WT__3G5(Y__R3>\`.$S>#P!3@"@!1H0JN
- XM`D:%4X-K``"(+!C,@2X1SH2.AB+'+!K,@2X3SH2.AB;'+`,BV%'.__PL`R;:.
- XM4<[__"P8S((N$<Z%CH8BQRP:S((N$\Z%CH8FQ]',T\W5S-?-+PLO"B1>)E8L#
- XM&LR!+A/.A(Z&)L<L`R;:4<[__"P:S((N$\Z%CH8FQ]7,U\TLBRT*)%\F7U'(!
- XM_X),WT__3G4L&,R!+A'.A(Z&(L<L&,R"+A'.A8Z&(L<L&LR!+A/.A(Z&)L<L0
- XM&LR"+A/.A8Z&)L?1S-/-U<S7S2\++PHD7B96+!K,@2X3SH2.AB;'+!K,@BX3L
- XMSH6.AB;'U<S7S2R++0HD7R9?4<C_FDS?3_].=4CG__)-[P`X3-X/`%.`*`%&,
- XMA"H"1H53@VL``*PL&,R!+A'.A(Z&(L<L&LR!+A/.A(Z&)L<L`R+84<[__"P#@
- XM)MI1SO_\+!C,@BX1SH6.AB+'+!K,@BX3SH6.AB;'T<S3S=7,U\U(YP#P3-8/V
- XM`"P8S($N$<Z$CH8BQRP:S($N$\Z$CH8FQRP#(MA1SO_\+`,FVE'.__PL&,R"D
- XM+A'.A8Z&(L<L&LR"+A/.A8Z&)L?1S-/-U<S7S4C6#P!,WP\`4<C_7DS?3_].>
- XM=2P8S($N$<Z$CH8BQRP8S((N$<Z%CH8BQRP:S($N$\Z$CH8FQRP:S((N$\Z%$
- XMCH8FQ]',T\W5S-?-2.<`\$S6#P`L&,R!+A'.A(Z&(L<L&,R"+A'.A8Z&(L<L_
- XM&LR!+A/.A(Z&)L<L&LR"+A/.A8Z&)L?1S-/-U<S7S4C6#P!,WP\`4<C_?DS?.
- XM3_].=4CG^,)-[P`D(%XB5E.`)`%&@B88QH$H$<B"B(,BQ-',T\U1R/_N3-]#Z
- XM'TYU2.?X\DWO`"Q,W@\`4X`D`4:")AC&@2@1R(*(@R+$)AK&@2@3R(*(@R;$6
- XMT<S3S=7,U\U1R/_>3-]/'TYU2.?X\DWO`"Q,W@\`4X`D`4:")AC&@2@1R(*(>
- XM@R+$)AK&@2@3R(*(@R;$T<S3S=7,U\TO"2\((%XB5B88QH$H$<B"B(,BQ-',G
- XMT\TLB2T((%\B7U'(_[Y,WT\?3G5(Y_CR3>\`+$S>#P!3@"0!1H(F&,:!*!'(\
- XM@HB#(L0F&L:!*!/(@HB#)L31S-/-U<S7S4CG`/!,U@\`)AC&@2@1R(*(@R+$_
- XM)AK&@2@3R(*(@R;$T<S3S=7,U\U(U@\`3-\/`%'(_ZY,WT\?3G5(YY-`?O]3>
- XM@"8#:RQ30VL8@YDL`R+'4<[__(69T\U1R/_P3-\"R4YU@YF%F=/-4<C_^$S?[
- XM`LE.=2P!S(*-F=/-4<C_^DS?`LE.=4CG\T!&@4:"?@!3@"8#:RQ30VL8PYDL]
- XM`R+'4<[__,69T\U1R/_P3-\"STYUPYG%F=/-4<C_^$S?`L].=2P!C(+-F=/-U
- XM4<C_^DS?`L].=?____]_____/____Q____\/____!____P/___\!____`/__M
- XM_P!___\`/___`!___P`/__\`!___``/__P`!__\``/__``!__P``/_\``!__`
- XM```/_P``!_\```/_```!_P```/\```!_````/P```!\````/````!P````,`+
- XM```!_____X````#`````X````/````#X````_````/X```#_````_X```/_`\
- XM``#_X```__```/_X``#__```__X``/__``#__X``___``/__X`#___``___XY
- XM`/___`#___X`____`/___X#____`____X/____#____X_____/____X``$CG/
- XM.#(L>``$<@!P)$ZN_SI*@&<``&PF0)/)3J[^VB1`(&H`K-'(T<@G:``\``1"=
- XMJ``\)KP````D1>L`""QY````'#3\*'PDS#3\3KDD[P`D-/PL?"3.1^L`!"8+&
- XMY(LT_"(\),,D_$[N_V0B+P`<)"\`("@O`"A.KO]V3-],'$YU<'A.^0```58@O
- XM+P`$#```86T*#```>FX$!```($YU``!.5?_\2.<#,"9O`!PD;P`@+B\`)$J'L
- XM9S9*$V<R2A)G+G``$!LO`$ZZ_\!R`!(:+H$O0``43KK_LEA/(B\`$)*`+`%*O
- XMAF<$(`9@&E.'8,9*AV<02A-G!'`!8`I*$F<$</]@`G``3-\,P$Y=3G4O"R9OX
- XM``AP`!`30>P#50@P``,(`&<$4HM@["`+)E].=0```````'!A(&\`!")(<@!P:
- XM`"\"#!``*V<!``+68"4D@0&`0``#!M$@P```EN#"0!Y8'2@M*!TH!@Y@P1!
- XM`"UF`D2!)!\@"%.`(&\`"""!D(E.=4CG`!(F;P`,2JL`"F<*(DLL>``$3J[^-
- XMF!=\`/\`"'#_)T``%'``$"L`#RQX``1.KOZP(DMP(DZN_RY,WT@`3G5(YP,RJ
- XM)F\`&"XO`!QP_RQX``1.KOZV?``<`'#_O(!F!'``8&9P(B(\``$``4ZN_SHD;
- XM0"`*9@@@!DZN_K!@2B5+``H@!Q5```D5?``$``A"*@`.(`850``/D\E.KO[:B
- XM)4``$"`+9P@B2DZN_IY@&D'J`!@E2``40>H`%"5(`!Q"J@`8%7P``@`@(`I,&
- XMWTS`3G5.5?_\+PLF;0`((`MF!'``8!8O"TZZ_J8F0$AM__PO"TZZ_L(@+?_\B
- XM)FW_^$Y=3G4```/L````"@```````!4<```.%@``#A(```X.```."@``#@8`N
- XM``X"```-_@``#?H```NX````#@````$``!36```,6```#"@```Y"```,<```"
- XM#$H```P>```,%```#`P```OL```+S@``"[````$V````#@````````/R```#`
- XMZ@```18`````````````````````````````````````````````````````!
- XM9&]S+FQI8G)A<GD`0W!U0FQI="!6,2XP,""I($5D9'D@0V%R<F]L;"P@07!R>
- XM(#$Y.3$N(%)E<&QA8V5S(&)L:71T97(@=VET:"`V.#`R,"\V.#`S,"X*57-A4
- XM9V4Z($-P=4)L:70@>V]P=&EO;G-]('P@>VME>7=O<F1S?0H*3W!T:6]N<SH*M
- XM("`@("UA("`@($%L=V%Y<R!U<V4@0U!5('1O(&1O(&)L:71S("AD969A=6QT5
- XM('-E='1I;F<I"B`@("`M,2`@("!5<V4@0U!5(&9O<B!B;&ET<R!U;FQE<W,@C
- XM86YO=&AE<B!T87-K(&ES(')E861Y('1O(')U;@H@("`@+3(@("`@57-E($-0V
- XM52!F;W(@8FQI=',@=6YL97-S(&UO<F4@=&AA;B!O;F4@=&%S:R!I<R!R96%D_
- XM>2!T;R!R=6X*("`@("UB("`@(%5S92!#4%4@979E;B!I9B!B:71M87`@:7-N#
- XM)W0@:6YI=&EA;&ES960@8V]R<F5C=&QY"B`@("`M;R`@("!5<V4@0U!5(&]N9
- XM;'D@=VAE;B!A('-I;F=L92!B:71M87`@:7,@:6YV;VQV960*("`@("US("`@$
- XM(%5S92!#4%4@9F]R(&)L:71S('5N;&5S<R!A(&)L:70@:7,@86QR96%D>2!I'
- XM;B!P<F]G<F5S<PH@("`@+7!.("`@26=N;W)E('1A<VMS('=I=&@@<')I;W)I3
- XM='D@/"!.("AD969A=6QT('-E='1I;F<@:7,@,"D*("`@("UQ("`@(%)E;6]VH
- XM92!#<'5";&ET(&9R;VT@=&AE('-Y<W1E;0H*2V5Y=V]R9',Z($),251-3T1%(
- XM/5M!3%=!65-\3TY%?%173WQ32$%215T@0E)/2T5.(%-)3D=,12!-24Y405-+#
- XM4%))/6X@455)5`H*4V5E('1H92!D;V-U;65N=&%T:6]N(&9O<B!D971A:6QS2
- XM(&%B;W5T('-T87)T:6YG($-P=4)L:70@9G)O;2!7;W)K8F5N8V@N"@`````,U
- XM>@``#%8```PF```,&@``````````````````_____P``#'H`````````````V
- XM````("`@("`@("`@*"@H*"@@("`@("`@("`@("`@("`@("!($!`0$!`0$!`0`
- XM$!`0$!`0A(2$A(2$A(2$A!`0$!`0$!"!@8&!@8$!`0$!`0$!`0$!`0$!`0$!.
- XM`0$!`1`0$!`0$(*"@H*"@@("`@("`@("`@("`@("`@("`@("$!`0$"`@("`@X
- XM("`@("`H*"@H*"`@("`@("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$D
- XMA(2$A(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0>
- XM$!`0@H*"@H*"`@("`@("`@("`@("`@("`@("`@(0$!`0(````````^P````%X
- X@`````````T0```,N```#*@```R8```,B`````````_(0X
- X``
- Xend
- Xsize 7232
- END_OF_FILE
- if test 10162 -ne `wc -c <'CpuBlit.uu'`; then
- echo shar: \"'CpuBlit.uu'\" unpacked with wrong size!
- fi
- # end of 'CpuBlit.uu'
- fi
- if test -f 'CpuBlit0.uu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CpuBlit0.uu'\"
- else
- echo shar: Extracting \"'CpuBlit0.uu'\" \(795 characters\)
- sed "s/^X//" >'CpuBlit0.uu' <<'END_OF_FILE'
- Xbegin 666 CpuBlit.info
- XMXQ```0``````&P`C`#H`%P`%``,``0?`Z6``````````````````````````<
- XM```!`U(`````!\#I>````!<````1`````````````!`````````Z`!8``@`"*
- XM:7`#````````````````0`````````#```"``````,```8``````P``!P```>
- XM``#```'``````,```(``````P`````````#``````````,``#```````P`$`.
- XM``````#``````````,``````````P`````````#``````````,``````/_X`]
- XMP`````'__\#`````\___\,````&____XP````?_'\?S``````````,!_____&
- XM____P/________^`P`&```````#!`\```````,'#X```````P?/@`!P```#`/
- XM^^``/@```,`_P``>````P`^``^P```#`'^`_^````,!S\?_\^```P?______]
- XM``#`?__]_^?``,`'__[^````P`/__`````#`#_?@`````,`_```7=```P/@`)
- XM`*JJ@`#````#=W=@`,```$*JJK``P````7U?0`#`````>`<``(``````````'
- XM````&````!1!551(3U(]161D>2!#87)R;VQL`````!!"3$E434]$13U!;'=A3
- XM>7,`````"E-)3D=,13U.;P`````*0E)/2T5./4YO``````I$3TY/5%=!250`Z
- X``
- Xend
- Xsize 540
- END_OF_FILE
- if test 795 -ne `wc -c <'CpuBlit0.uu'`; then
- echo shar: \"'CpuBlit0.uu'\" unpacked with wrong size!
- fi
- # end of 'CpuBlit0.uu'
- fi
- if test -f 'History' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'History'\"
- else
- echo shar: Extracting \"'History'\" \(2257 characters\)
- sed "s/^X//" >'History' <<'END_OF_FILE'
- XHISTORY
- X
- X
- X Version 1.00, 20 Apr 1991
- X
- X First release to the public. (No changes since V0.98.)
- X
- X
- X Version 0.98, 10 Apr 1991
- X
- X Added Workbench support and ReadArgs-style command line arguments.
- X Also added MinTaskPri option to allow CpuBlit to ignore background
- X tasks when deciding whether it should do a blit or not. If running
- X under 1.3, CpuBlit uses its own version of FindPort() instead of
- X Exec's version which causes Enforcer hits on an A3000. No bugs
- X reported since V0.97, so it looks like the blit code itself is
- X pretty stable now (famous last words).
- X
- X
- X Version 0.97, 17 Feb 1991
- X
- X Fixed bug in handling blits which had a negative Y offset.
- X Previously, the negative Y offset got changed into a large positive
- X Y offset; if this was the destination offset, random memory could
- X get trashed. Now works fine with Shanghai.
- X
- X
- X Version 0.96, 14 Feb 1991
- X
- X Fixed bug in handling of single plane bitmaps. Added check to ensure
- X blits with zero width don't cause surprising results. Modified
- X command line parsing to handle multiple arguments, since the
- X various parameters are no longer all mutually exclusive. Tidied up
- X source a little.
- X
- X
- X Version 0.95, 9 Feb 1991
- X
- X Now handles being run from a disk with a space in its name properly
- X (for example "RAM DISK:CpuBlit"). Previously, everything after the
- X space got treated as a command line option. Also added some checks
- X to ensure upwards compatibility with future Amigas.
- X
- X
- X Version 0.93, 7 Feb 1991
- X
- X Bug in the handling of Workbench 2.0 $00000000 and $FFFFFFFF bitplane
- X pointers is now fixed. Since Workbench 2.0 uses these for gadgetry
- X etc, this was causing quite a few problems under 2.0. Also fixed a
- X small nasty bug that arrived with CpuBlit 0.92.
- X
- X
- X Version 0.92, 6 Feb 1991
- X
- X Now correctly handles the case where the source and destination
- X bitmaps do not have equal numbers of bitplanes. Also fixed problem
- X where CpuBlit was (incorrectly) intercepting blits with minterms of
- X $D0, $E0 or $F0.
- X
- X
- X Version 0.91, 5 Feb 1991
- X
- X Added `-o' option to help track down the source of CpuBlit
- X incompatibilities.
- X
- X
- X Version 0.90, 3 Feb 1991
- X
- X Initial release. Currently thought to be bug free, but undoubtedly
- X this will change once users get their hands on it :-)
- END_OF_FILE
- if test 2257 -ne `wc -c <'History'`; then
- echo shar: \"'History'\" unpacked with wrong size!
- fi
- # end of 'History'
- fi
- if test -f 'Kill_CpuBli.uu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Kill_CpuBli.uu'\"
- else
- echo shar: Extracting \"'Kill_CpuBli.uu'\" \(713 characters\)
- sed "s/^X//" >'Kill_CpuBli.uu' <<'END_OF_FILE'
- Xbegin 666 Kill_CpuBlit.info
- XMXQ```0``````?``C`#H`%P`$``,``0?`*0@`````````````````````````D
- XM```!!%('P".@!\`IH````'@````1`````````````!`````````Z`!8``@`">
- XM:!`#````````````````0`````````#```"`_^```,```8\`'@``P``!\``!Z
- XMP`#```'\``!P`,```X<``!@`P``&`<``#`#```8`<``,`,``#``<``8`P`$,?
- XM``<`!@#```P``<`&`,``!@``<`P`P``&```<#`#```,```<8`,```<``/_X`P
- XMP```<`'__\#````/\___\,````'____XP````?_'\?S``````````,!_____%
- XM____P/________^`P`&```````#!`\```````,'#X```````P?.``!P```#`O
- XM^@``/@```,`\P``>````P`F``^P```#`&>`/^````,!S\>/\^```P?/_^/_YH
- XM``#`<__\/^'``,`!__Z.````P`'__`````#`#/?@`````,`^```6!```P/@`)
- XM`*HJ@`#````#87=@`,`````*JK``P````7U?0`#`````>`<``(``````````/
- X9````"$-P=4)L:70`````"`````5154E4`'U?G
- X``
- Xend
- Xsize 475
- END_OF_FILE
- if test 713 -ne `wc -c <'Kill_CpuBli.uu'`; then
- echo shar: \"'Kill_CpuBli.uu'\" unpacked with wrong size!
- fi
- # end of 'Kill_CpuBli.uu'
- fi
- if test ! -d 'src' ; then
- echo shar: Creating directory \"'src'\"
- mkdir 'src'
- fi
- if test -f 'src/cpublit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cpublit.c'\"
- else
- echo shar: Extracting \"'src/cpublit.c'\" \(15098 characters\)
- sed "s/^X//" >'src/cpublit.c' <<'END_OF_FILE'
- X/****************************************************************************
- X *
- X * CPUBLIT.C
- X *
- X * (C) Copyright Eddy Carroll, 1991. Freely distributable.
- X *
- X * CpuBlit replaces the BltBitMap function in graphics.library with
- X * a version that uses the CPU where practical. This is up to 2.8
- X * times faster on a 68030 system.
- X *
- X * This module installs the new blit routine, handles parsing the
- X * command line options etc. Scroll.s does the actual blitting.
- X *
- X ***************************************************************************/
- X
- X#define DEBUG 0 /* If 1, then include debugging code */
- X
- X#ifndef LATTICE_50
- X#include "system.h"
- Xtypedef void (*__fptr)(); /* The sort of thing returned by SetFunction */
- X#endif
- X
- X#include "scroll.h"
- X
- X#define YES 1
- X#define NO 0
- X
- X#define NAME "CpuBlit V1.00"
- X#define PORTNAME NAME
- X#define SIGNON NAME " \251 1991 Eddy Carroll.\n"
- X#define DATE "Apr 1991"
- X
- X#define print(s) Write(Output(), s, strlen(s))
- X#define BltBitMap_LVO (-30) /* Offset of BltBitMap in graphics.library */
- X
- Xchar HelpMsg[] =
- XNAME " \251 Eddy Carroll, " DATE ". Replaces blitter with 68020/68030.\n"
- X"Usage: CpuBlit {options} | {keywords}\n"
- X"\n"
- X"Options:\n"
- X" -a Always use CPU to do blits (default setting)\n"
- X" -1 Use CPU for blits unless another task is ready to run\n"
- X" -2 Use CPU for blits unless more than one task is ready to run\n"
- X" -b Use CPU even if bitmap isn't initialised correctly\n"
- X" -o Use CPU only when a single bitmap is involved\n"
- X" -s Use CPU for blits unless a blit is already in progress\n"
- X" -pN Ignore tasks with priority < N (default setting is 0)\n"
- X" -q Remove CpuBlit from the system\n"
- X"\n"
- X"Keywords: BLITMODE=[ALWAYS|ONE|TWO|SHARE] BROKEN SINGLE MINTASKPRI=n QUIT\n"
- X"\n"
- X"See the documentation for details about starting CpuBlit from Workbench.\n";
- X
- X/****************************************************************************
- X *
- X * Globals
- X *
- X ***************************************************************************/
- X
- Xstruct Gfxbase *GfxBase;
- Xstruct IntuitionBase *IntuitionBase;
- Xstruct IconBase *IconBase;
- X
- X/*
- X * Valid modes of operation for BlitMode
- X */
- X#define BLIT_ALWAYS 0 /* Always use CPU for blits */
- X#define BLIT_ONE 1 /* Use CPU unless another task is ready to run */
- X#define BLIT_TWO 2 /* Use CPU unless more than one task is ready */
- X#define BLIT_SHARE 3 /* Use CPU unless CPU is already doing a blit */
- X
- X/*
- X * This array corresponds to the above modes
- X */
- Xvoid (*BlitFuncs[])() = { StartBlit, Friend1, Friend2, ShareBlit };
- X
- X/*
- X * All the settings that can be set by the program
- X */
- Xstruct Settings {
- X long BlitMode; /* Current mode of operation for blits */
- X long OnlySingle; /* True if restricting blits to 1 bmap */
- X long Broken; /* True if handling broken software */
- X BYTE MinTaskPri; /* All tasks less than this are ignored */
- X} Settings = {
- X BLIT_ALWAYS, NO, NO, 0
- X};
- X
- X/*
- X * Commands that we can send in a message
- X */
- X#define MSG_GETVARS 0 /* Get copy of current CpuBlit settings */
- X#define MSG_SETVARS 1 /* Update CpuBlit settings */
- X#define MSG_QUIT 2 /* Remove background copy of CpuBlit */
- X
- Xstruct MyMsg {
- X struct Message msg; /* Standard message structure */
- X struct Settings *vars; /* Settings used by CpuBlit */
- X int command; /* Requested operation */
- X int result; /* True if command completed okay */
- X} MyMsg, *msg;
- X
- X/*
- X * Return codes passed back in result
- X */
- X#define MSG_OKAY 0 /* Message was handled correctly */
- X#define MSG_REMOVED 1 /* CpuBlit was removed safely */
- X#define MSG_FAILED 2 /* CpuBlit couldn't be removed */
- X
- X/*
- X * Scalar variables
- X */
- Xstruct MsgPort *LocalPort; /* Local port for returned messages */
- Xlong QuitFlag; /* True if user asks CpuBlit to quit */
- Xlong FromWorkbench; /* True if started from Workbench */
- Xlong AlreadyRunning; /* True if CpuBlit already installed */
- X
- X/****************************************************************************
- X *
- X * myexit(err)
- X *
- X * Performs a small amount of cleanup and then exits to AmigaDos.
- X * Principally, handles cleaning up if we were run from Workbench.
- X *
- X ***************************************************************************/
- X
- Xvoid myexit(err)
- X{
- X if (LocalPort)
- X DeletePort(LocalPort);
- X
- X exit(err);
- X}
- X
- X/****************************************************************************
- X *
- X * SetVars(settings)
- X *
- X * Sets the various CpuBlit flags according to the values in the
- X * supplied Settings structure.
- X *
- X ***************************************************************************/
- X
- Xvoid SetVars(struct Settings *settings)
- X{
- X BlitFunc = BlitFuncs[settings->BlitMode];
- X OnlySingle = settings->OnlySingle;
- X Broken = settings->Broken;
- X MinTaskPri = settings->MinTaskPri;
- X}
- X
- X/****************************************************************************
- X *
- X * ParseOption()
- X *
- X * Parses an option string, setting the appropriate field in the
- X * master Settings structure. This routine handles both Unix-style
- X * -opts and also ReadArgs/ToolTypes keywords. Returns true if
- X * the option string made sense, false otherwise.
- X *
- X ***************************************************************************/
- X
- Xint ParseOption(char *opt)
- X{
- X#define MATCHSTR(s1,s2) (!strnicmp(s1, s2, sizeof(s2)-1))
- X
- X if MATCHSTR(opt, "-a") {
- X Settings.BlitMode = BLIT_ALWAYS;
- X Settings.OnlySingle = NO;
- X Settings.Broken = NO;
- X }
- X else if MATCHSTR(opt, "-1") Settings.BlitMode = BLIT_ONE;
- X else if MATCHSTR(opt, "-2") Settings.BlitMode = BLIT_TWO;
- X else if MATCHSTR(opt, "-s") Settings.BlitMode = BLIT_SHARE;
- X else if MATCHSTR(opt, "-b") Settings.Broken = YES;
- X else if MATCHSTR(opt, "-o") Settings.OnlySingle = YES;
- X else if MATCHSTR(opt, "-q") QuitFlag = YES;
- X else if (MATCHSTR(opt, "-p") && opt[2])
- X Settings.MinTaskPri = atoi(opt+2);
- X else if MATCHSTR(opt, "BLITMODE") {
- X char *p = opt + 8;
- X if (*p++ && *p) {
- X if MATCHSTR(p, "ALWAYS") Settings.BlitMode = BLIT_ALWAYS;
- X else if MATCHSTR(p, "ONE") Settings.BlitMode = BLIT_ONE;
- X else if MATCHSTR(p, "TWO") Settings.BlitMode = BLIT_TWO;
- X else if MATCHSTR(p, "SHARE") Settings.BlitMode = BLIT_SHARE;
- X } else return (0);
- X }
- X else if MATCHSTR(opt, "BROKEN") {
- X char *p = opt + 6;
- X if (*p++ && MATCHSTR(p, "NO")) Settings.Broken = NO;
- X else Settings.Broken = YES;
- X }
- X else if MATCHSTR(opt, "SINGLE") {
- X char *p = opt + 6;
- X if (*p++ && MATCHSTR(p, "NO")) Settings.OnlySingle = NO;
- X else Settings.OnlySingle = YES;
- X }
- X else if MATCHSTR(opt, "MINTASKPRI") {
- X char *p = opt + 10;
- X if (*p++ && *p) Settings.MinTaskPri = atoi(p);
- X else return (0);
- X }
- X else if MATCHSTR(opt, "QUIT") QuitFlag = YES;
- X else return (0);
- X
- X return (1);
- X}
- X
- X/****************************************************************************
- X *
- X * MyFindPort(name)
- X *
- X * Replacement for the FindPort() in exec.library. Under 1.3, FindPort()
- X * will cause Enforcer hits since FFS partitions create public ports
- X * that have no name (this is a no-no), and FindPort() doesn't check
- X * for null names.
- X *
- X * Even though this isn't really CpuBlit's problem, I had quite a few
- X * reports of CpuBlit causing Enforcer hits which turned out to be
- X * because of this, so I've added this workaround to keep people
- X * happy.
- X *
- X * Commodore made FindPort() (actually FindName()) a bit more robust
- X * under Kickstart 2.0, so in that case we can safely use the standard
- X * routine.
- X *
- X ***************************************************************************/
- X
- Xstruct MsgPort *MyFindPort(char *name)
- X{
- X struct Node *nd;
- X extern struct ExecBase *SysBase;
- X
- X if (SysBase->LibNode.lib_Version >= 36)
- X return (FindPort(name));
- X
- X Forbid();
- X for (nd = SysBase->PortList.lh_Head; nd; nd = nd->ln_Succ)
- X if (nd->ln_Name && !strcmp(nd->ln_Name, name))
- X break;
- X Permit();
- X return (struct MsgPort *)nd;
- X}
- X
- X
- X/****************************************************************************
- X *
- X * mainloop()
- X *
- X * This is the main event loop. It sits waiting for a message from
- X * other invocations of CpuBlit, which tell it to either change the
- X * current settings or to remove itself.
- X *
- X ***************************************************************************/
- X
- Xvoid mainloop(void)
- X{
- X struct MsgPort *MyPort;
- X int installed = 1;
- X __fptr *BltBitMapPtr = (__fptr *)BltBitMapAddress;
- X
- X /*
- X * We have to create our rendezvous port here rather than in the
- X * mainline, since the message port depends on task information etc.
- X * This is not altogether satisfactory since if it fails, there is
- X * no way to tell the user (as a background task, we have no stdin
- X * or stdout). But since port creation is unlikely to fail anyway,
- X * it's not a big problem.
- X */
- X MyPort = CreatePort(PORTNAME, 0);
- X if (!MyPort)
- X return;
- X
- X /*
- X * Now have to open graphics.library, so that we can add in our
- X * new patch. As above, if this fails there is no easy way to
- X * tell the user. However, at least it won't crash the system.
- X */
- X GfxBase = OpenLibrary("graphics.library", 0);
- X if (!GfxBase)
- X return;
- X
- X *BltBitMapPtr = SetFunction(GfxBase, BltBitMap_LVO, NewBltBitMap);
- X
- X /*
- X * Now wait a message from another copy of CpuBlit. This will
- X * either contain an updated command line argument or else a
- X * request to quit.
- X */
- X do {
- X __fptr oldptr;
- X
- X WaitPort(MyPort);
- X while ((msg = (struct MyMsg *)GetMsg(MyPort)) != NULL) {
- X switch (msg->command) {
- X
- X case MSG_GETVARS:
- X memcpy(msg->vars, &Settings, sizeof(Settings));
- X break;
- X
- X case MSG_SETVARS:
- X memcpy(&Settings, msg->vars, sizeof(Settings));
- X SetVars(&Settings);
- X break;
- X
- X case MSG_QUIT:
- X /*
- X * Try and remove ourselves. We have to surround this
- X * with Forbid() to make sure that no other tasks manage
- X * to call BltBitMap() in the case where we restore the
- X * original vector and then realise that its current
- X * replacement actually pointed to something other than
- X * CpuBlit.
- X */
- X Forbid();
- X oldptr = SetFunction(GfxBase, BltBitMap_LVO, *BltBitMapPtr);
- X if (oldptr == NewBltBitMap) {
- X installed = 0;
- X msg->result = MSG_REMOVED;
- X } else {
- X SetFunction(GfxBase, BltBitMap_LVO, oldptr);
- X msg->result = MSG_FAILED;
- X }
- X Permit();
- X }
- X ReplyMsg(msg);
- X }
- X } while (installed);
- X
- X /*
- X * Now our patch has been removed, it only remains to free up the
- X * code. It is possible that someone is still in our blitter code.
- X * We can determine this fairly safely by looking at UsageCount;
- X * if this is -1, nobody is in our code. Otherwise, we wait until
- X * it is -1 (delaying for a little while inbetween to give programs
- X * a chance to run).
- X *
- X * We also set the blitter test function to ExitBlit, so that if
- X * someone does slip through our test and end up inside our code,
- X * they will get rerouted back to the normal blitter code almost
- X * immediately.
- X */
- X DeletePort(MyPort);
- X BlitFunc = ExitBlit;
- X
- X while (UsageCount != -1)
- X Delay(10); /* Wait 0.2 seconds */
- X
- X /*
- X * Now we're completely finished so we can close the libraries
- X * and exit.
- X */
- X CloseLibrary(GfxBase);
- X}
- X
- X
- X/****************************************************************************
- X *
- X * Mainline
- X *
- X ***************************************************************************/
- X
- Xvoid main(int argc, char **argv)
- X{
- X struct MsgPort *BlitPort;
- X int i;
- X
- X FromWorkbench = (argc == 0);
- X
- X /*
- X * Now see if CpuBlit is already running in
- X * the background. If it is, then get a copy of the settings it
- X * is currently using.
- X */
- X BlitPort = MyFindPort(PORTNAME);
- X if (BlitPort) {
- X /*
- X * The new blit routine has already been installed. So, send
- X * it a message giving the command line options (if any)
- X * to the remote routine, telling it to update its own options.
- X */
- X AlreadyRunning = YES;
- X LocalPort = CreatePort(NULL, 0);
- X if (!LocalPort) {
- X if (!FromWorkbench)
- X print("CpuBlit: couldn't create local message port.\n");
- X myexit(10);
- X }
- X MyMsg.msg.mn_ReplyPort = LocalPort;
- X MyMsg.command = MSG_GETVARS;
- X MyMsg.vars = &Settings;
- X PutMsg(BlitPort, &MyMsg);
- X WaitPort(LocalPort);
- X GetMsg(LocalPort);
- X }
- X /*
- X * Now parse the command line options, modifying our local copy
- X * of Settings accordingly.
- X */
- X if (FromWorkbench) {
- X extern struct WBStartup *WBenchMsg;
- X struct WBArg *wbarg = WBenchMsg->sm_ArgList;
- X
- X IconBase = (struct IconBase *)OpenLibrary("icon.library", 0);
- X if (!IconBase)
- X myexit(5);
- X
- X /*
- X * Now walk down all the icons we've been given (probably
- X * just our own tool icon) and parse the arguments present
- X * in each one.
- X */
- X for (i = 0; i < WBenchMsg->sm_NumArgs; i++, wbarg++) {
- X struct DiskObject *dobj;
- X char **tooltypes;
- X BPTR olddir;
- X
- X if (wbarg->wa_Lock && *wbarg->wa_Name) {
- X olddir = CurrentDir(wbarg->wa_Lock);
- X if (dobj = GetDiskObject(wbarg->wa_Name)) {
- X for (tooltypes = dobj->do_ToolTypes;
- X *tooltypes; tooltypes++)
- X ParseOption(*tooltypes);
- X }
- X FreeDiskObject(dobj);
- X CurrentDir(olddir);
- X }
- X }
- X CloseLibrary(IconBase);
- X } else {
- X /*
- X * Plain jane CLI startup
- X */
- X#if DEBUG
- X if (argv[1][0] == '!') {
- X static buf[1000];
- X sprintf(buf,
- X "Blitmode = %d\n"
- X "OnlySingle = %d\n"
- X "Broken = %d\n"
- X "MinTaskPri = %d\n",
- X Settings.BlitMode, Settings.OnlySingle,
- X Settings.Broken, Settings.MinTaskPri);
- X print(buf);
- X exit(5);
- X }
- X#endif
- X for (i = 1; i < argc; i++) {
- X if (!ParseOption(argv[i])) {
- X print(HelpMsg);
- X myexit(5);
- X }
- X }
- X }
- X
- X /*
- X * Now we either send the options to the remote copy of CpuBlit
- X * or install ourselves in the background.
- X */
- X if (AlreadyRunning) {
- X if (QuitFlag)
- X MyMsg.command = MSG_QUIT;
- X else
- X MyMsg.command = MSG_SETVARS;
- X PutMsg(BlitPort, &MyMsg);
- X WaitPort(LocalPort);
- X GetMsg(LocalPort);
- X if (FromWorkbench && MyMsg.result == MSG_FAILED) {
- X IntuitionBase = (struct IntuitionBase *)
- X OpenLibrary("intuition.library", 0);
- X if (IntuitionBase) {
- X DisplayBeep(0); /* Flash all screens -- pretty rude */
- X CloseLibrary(IntuitionBase);
- X }
- X }
- X if (!FromWorkbench) {
- X if (MyMsg.result == MSG_REMOVED)
- X print("CpuBlit removed successfully.\n");
- X else if (MyMsg.result == MSG_FAILED) {
- X print(
- X"Couldn't remove CpuBlit; someone else has patched BltBitMap. Please remove\n"
- X"any other utilities you have installed and then try again.\n");
- X myexit(5);
- X }
- X }
- X myexit(0);
- X }
- X
- X /*
- X * This is the first time we are being run. If we were run from
- X * the CLI, detach ourselves (and allow the current process to
- X * return to the CLI immediately). If we were run from Workbench,
- X * then just call the message handling code directly and wait
- X * until another copy of CpuBlit asks us to return.
- X */
- X if (QuitFlag) {
- X if (!FromWorkbench)
- X print("CpuBlit hasn't been installed yet.\n");
- X myexit(5);
- X }
- X
- X SetVars(&Settings);
- X if (FromWorkbench)
- X mainloop();
- X else {
- X if (!res(NAME, 5, mainloop, 4000)) {
- X print("Couldn't spawn background CpuBlit task.\n");
- X myexit(10);
- X }
- X print(SIGNON);
- X }
- X myexit(0);
- X}
- END_OF_FILE
- if test 15098 -ne `wc -c <'src/cpublit.c'`; then
- echo shar: \"'src/cpublit.c'\" unpacked with wrong size!
- fi
- # end of 'src/cpublit.c'
- fi
- if test -f 'src/makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/makefile'\"
- else
- echo shar: Extracting \"'src/makefile'\" \(821 characters\)
- sed "s/^X//" >'src/makefile' <<'END_OF_FILE'
- X#
- X# Lattice LKM makefile, for SAS/C C V5.10a :ts=8
- X#
- X# CpuBlit (C) Copyright Eddy Carroll, Feb 1991
- X#
- X
- X#DBSYM = -d5
- XCFLAGS = -cusq -j88i -ms -v $(DBSYM)
- XBFLAGS = sc sd nd map ram:map
- X#BFLAGS = sc sd map ram:map addsym
- XLIBS = lib:lc.lib lib:amiga.lib
- XASM = lc:asm
- X
- X.c.o:
- X lc $(CFLAGS) -Hsystem.sym $*.c
- X.s.o:
- X $(ASM) -iinclude: $*.s # Standard "pure" assembly
- X.a.o:
- X $(ASM) -u -iinclude: $*.a # Prefixes all labels with style underscore
- X.n.doc:
- X nro >$*.doc -ms:an $*.n
- X.h.sym:
- X lc1 -ph -o$*.sym $*.h
- X
- X#
- X# Makefile dependencies
- X#
- X
- XNAME = cpublit
- X
- Xall: $(NAME)
- X
- XOBJS = small.o $(NAME).o scroll.o res.o
- X
- X$(NAME): $(OBJS) makefile
- X blink from $(OBJS) to $(NAME) $(BFLAGS) lib $(LIBS)
- X
- Xsystem.sym: system.h
- Xcpublit.o: cpublit.c scroll.h system.sym
- Xsmall.o: small.a
- Xscroll.o: scroll.s
- Xres.o: res.s
- END_OF_FILE
- if test 821 -ne `wc -c <'src/makefile'`; then
- echo shar: \"'src/makefile'\" unpacked with wrong size!
- fi
- # end of 'src/makefile'
- fi
- if test -f 'src/res.s' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/res.s'\"
- else
- echo shar: Extracting \"'src/res.s'\" \(6516 characters\)
- sed "s/^X//" >'src/res.s' <<'END_OF_FILE'
- X*:ts=8
- X*****************************************************************************
- X* *
- X* RES.S (C) Copyright Eddy Carroll 1989 *
- X* *
- X* This module allows you to make a duplicate copy of your current process. *
- X* In fact, both processes actually share the same code. However, the *
- X* seglist pointer of the current process is modified so that when the *
- X* process terminates, the memory doesn't get freed (if it did, the new *
- X* process would suddenly find itself deallocated. Hello guru...) *
- X* This code only works when called from CLI processes. *
- X* *
- X* The parameters passed are similar to those for CreateProc(), with the *
- X* difference that instead of passing a BPTR to a seglist, you pass the *
- X* address of the function the new process should start executing at. *
- X* *
- X* When the new process returns from this function, it will be removed from *
- X* the system, and its memory (finally) deallocated. *
- X* *
- X* The typical use for a function like this is to allow a program to detach *
- X* itself from a CLI (completely, with no trailing console handles etc.) *
- X* when it is run. This is a convenient feature for the user, if the program *
- X* is of the sort designed to sit in the background the whole time, rather *
- X* than do something immediately, then exit. *
- X* *
- X* Lattice provide cback.o which at first glance would seem to provide a *
- X* similar solution. However, cback.o makes it difficult to print error *
- X* messages to the console if there is an error on the command line - by *
- X* the time you spot the error, the CLI prompt has already been printed *
- X* and your error message is printed after it. This looks very messy. *
- X* Res avoids this problem by not spawning the background process until *
- X* after the error checking has been done. *
- X* *
- X* From C, you call it as follows: *
- X* *
- X* pid = res(name,pri,func,stacksize) *
- X* *
- X* name - pointer to null terminated string *
- X* pri - integer, priority of the new process *
- X* func - pointer to the function for new process to call *
- X* stacksize - integer, size of the stack for the new process *
- X* *
- X* pid - Process ID of new process, or 0 if none created *
- X* *
- X*****************************************************************************
- X
- X INCLUDE "exec/types.i"
- X INCLUDE "exec/alerts.i"
- X INCLUDE "exec/nodes.i"
- X INCLUDE "exec/lists.i"
- X INCLUDE "exec/ports.i"
- X INCLUDE "exec/libraries.i"
- X INCLUDE "exec/tasks.i"
- X INCLUDE "libraries/dos.i"
- X INCLUDE "libraries/dosextens.i"
- X INCLUDE "workbench/startup.i"
- X INCLUDE "exec/funcdef.i"
- X INCLUDE "exec/exec_lib.i"
- X INCLUDE "libraries/dos_lib.i"
- X
- X xref _exit
- X xref _DOSBase
- X xdef _res
- X
- XAbsExecBase equ 4
- Xsegsize equ 36 ; Size of fake seg. (code = 28 bytes)
- X
- X csect text,0,0,1,2 * xref's after this are 16-bit reloc
- X
- X
- Xcallsys macro
- X CALLLIB _LVO\1
- X endm
- X
- X_res:
- X movem.l d2-d4/a2/a3/a6,-(a7) ; Save registers
- X move.l AbsExecBase.w,a6 ; Get base of Exec library
- X moveq #0,d1 ; Any sort of memory will do
- X moveq #segsize,d0 ; Get size of fake segment
- X callsys AllocMem ; Grab some memory
- X tst.l d0 ; Did we get any?
- X beq fatal ; If not, abort immediately!
- X move.l d0,a3 ; Save pointer to memory
- X sub.l a1,a1 ; NULL pointer indicates our process
- X callsys FindTask ; Get pointer to our process block
- X move.l d0,a2 ; Save it
- X move.l pr_CLI(A2),a0 ; Get BPTR to our process's segarray
- X add.l a0,a0 ; Convert BPTR to address
- X add.l a0,a0 ;
- X move.l cli_Module(a0),4(a3) ; Make fake segment point to our code
- X clr.l cli_Module(a0) ; Remove process seg. from CLI seglist
- X move.l #segsize,(a3) ; Set size of fake seglist
- X lea.l 8(a3),a2 ; Get pointer to first code byte
- X
- X;
- X; Now a tiny machine code program is constructed. It looks like this:
- X;
- X; move.l #$xxxxxx,A4 ; Initialise A4
- X; jsr $xxxxxx ; Call user program
- X; move.l #$xxxxxx,A6 ; Load DOSbase into A6
- X; move.l #$xxxxxx,d1 ; Get BPTR to this segment
- X; jmp UnLoadSeg(A6) ; Unload our process from memory
- X;
- X; It's built "on the fly" so to speak, to keep code size down, and also
- X; because it's a convenient way of initialising all the variables.
- X; Note that a potential problem exists if DOSBase should somehow alter or
- X; disappear. We'll assume it will remain relatively stable for the next
- X; few years anyway :-)
- X;
- X
- X move.l _DOSBase,a6 ; Prepare for DOS call
- X move.w #$287C,(a2)+ ; Store MOVE.L $xxxxxx,A4 instruction
- X move.l a4,(a2)+ ; Output value of A4 to initialise to
- X move.w #$4EB9,(a2)+ ; Store JSR $xxxxxx
- X move.l 36(a7),(a2)+ ; followed by address of user function
- X move.w #$2C7C,(a2)+ ; Store MOVE.L $xxxxxx,A6 instruction
- X move.l a6,(a2)+ ; followeds by current DOSbase
- X;
- X lea 4(a3),a3 ; Now get seglist ptr to fake segment
- X move.l a3,d3 ; and convert it to BPTR
- X lsr.l #2,d3 ; D3 now has seglist ptr to fake seg
- X move.w #$223C,(a2)+ ; Store MOVE.L $xxxxxx,D1 instruction
- X move.l d3,(a2)+ ; Followed by BPTR to the segment
- X move.l #$4EEEFF64,(a2)+ ; Store JMP UnLoadSeg(A6)
- X;
- X move.l 28(A7),d1 ; Get pointer to name
- X move.l 32(A7),d2 ; Get process priority
- X move.l 40(A7),d4 ; Get stacksize
- X callsys CreateProc ; Create new process
- X movem.l (a7)+,d2-d4/a2/a3/a6 ; Pop registers
- X rts ; Return
- Xfatal:
- X moveq #120,d0 ; Set error exit code
- X jmp _exit ; And exit
- X
- X end
- END_OF_FILE
- if test 6516 -ne `wc -c <'src/res.s'`; then
- echo shar: \"'src/res.s'\" unpacked with wrong size!
- fi
- # end of 'src/res.s'
- fi
- if test -f 'src/scroll.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/scroll.h'\"
- else
- echo shar: Extracting \"'src/scroll.h'\" \(1524 characters\)
- sed "s/^X//" >'src/scroll.h' <<'END_OF_FILE'
- X/****************************************************************************
- X *
- X * SCROLL.H
- X *
- X * Declares functions and variables available in the assembly
- X * file SCROLL.S.
- X *
- X * We have to do a little trick to allow the smalldata model to be
- X * used with Blink. We want to modify the longword stored at
- X * BltBitMapAddress. However, this is located in the code section
- X * of the program. The solution is to declare it as a function, then
- X * setup a pointer to it from inside the actual code and modify it
- X * through the pointer. This is a little ugly, but reduces the code
- X * size by about 20%.
- X *
- X ***************************************************************************/
- X
- Xextern void NewBltBitMap(); /* Our replacement BltBitMap routine */
- Xextern void BltBitMapAddress(); /* Points to original BltBitMap() */
- X
- Xextern void Friend1(); /* Ptr to check fn for one active task */
- Xextern void Friend2(); /* Ptr to check fn for two active tasks */
- Xextern void ShareBlit(); /* Ptr to check fn to share CPU/blitter */
- Xextern void StartBlit(); /* Ptr to check fn that always uses CPU */
- Xextern void ExitBlit(); /* Ptr to check fn that never uses CPU */
- X
- Xextern void (*BlitFunc)(); /* Holds Ptr to current check function */
- Xextern long UsageCount; /* No. of callers currently in CPU code */
- Xextern long OnlySingle; /* True if restricting blits to 1 bmap */
- Xextern long Broken; /* True if handling broken software */
- Xextern BYTE MinTaskPri; /* Ignore tasks with pri <= this value */
- END_OF_FILE
- if test 1524 -ne `wc -c <'src/scroll.h'`; then
- echo shar: \"'src/scroll.h'\" unpacked with wrong size!
- fi
- # end of 'src/scroll.h'
- fi
- if test -f 'src/small.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/small.a'\"
- else
- echo shar: Extracting \"'src/small.a'\" \(7425 characters\)
- sed "s/^X//" >'src/small.a' <<'END_OF_FILE'
- X*:ts=8
- X******************************************************************************
- X* *
- X* SMALL.A (C) Copyright Eddy Carroll 1991 *
- X* ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
- X* *
- X* Replacement startup code for Lattice C V5.10a. Use instead of c.o. *
- X* This has many features stripped out to allow small utilities to *
- X* have as small a filesize as possible. If you use this, don't call *
- X* any stdio functions. *
- X* *
- X* In some of my earlier projects, I used a similar file called tiny.a. *
- X* Small.a is essentially that file but with Workbench support added. *
- X* avoid confusion between the two. *
- X* *
- X******************************************************************************
- X
- X INCLUDE "exec/types.i"
- X INCLUDE "exec/execbase.i"
- X INCLUDE "exec/nodes.i"
- X INCLUDE "exec/lists.i"
- X INCLUDE "exec/ports.i"
- X INCLUDE "exec/libraries.i"
- X INCLUDE "exec/tasks.i"
- X INCLUDE "libraries/dos.i"
- X INCLUDE "libraries/dosextens.i"
- X INCLUDE "workbench/startup.i"
- X INCLUDE "exec/funcdef.i"
- X INCLUDE "exec/exec_lib.i"
- X INCLUDE "libraries/dos_lib.i"
- X
- XMAXARGS EQU 100 ; Maximum number of command line arguments from CLI
- XAbsExecBase EQU 4 ; Welcome to the only fixed point in the universe
- X
- X* A useful macro to let us call library routines
- Xcallsys macro
- X CALLLIB _LVO\1
- X endm
- X
- X xdef XCEXIT
- X xdef exit
- X xref LinkerDB
- X xref _BSSBAS
- X xref _BSSLEN
- X
- X csect text,0,0,1,2 * xref's after this are 16-bit reloc
- X xref main * Name of C program to start with.
- X
- Xstart:
- X movem.l d1-d6/a0-a6,-(a7)
- XREGSIZE EQU (6+7)*4
- X lea REGSIZE(a7),A5 * Determine old stack pointer
- X move.l a0,a2 * Save command pointer
- X move.l d0,d2 * and command length
- X lea LinkerDB,a4 * Load base register
- X
- X move.l AbsExecBase.W,a6
- X move.l a6,SysBase(A4)
- X move.l a7,_StackPtr(A4) * Save stack ptr
- X
- X move.l a5,D0 * get top of stack
- X sub.l 4(a5),D0 * compute bottom
- X add.l #128,D0 * allow for parms overflow
- X move.l D0,_base(A4) * save for stack checking
- X
- X lea DOSName(A4),A1
- X moveq.l #0,D0
- X callsys OpenLibrary
- X move.l D0,DOSBase(A4)
- X beq NoDos
- X
- X move.l ThisTask(a6),a3 * Get our task ID
- X tst.l pr_CLI(a3) * Running from Workbench?
- X bne.s getcom * If no, skip to do CLI stuff
- X lea pr_MsgPort(a3),a0 * Our process port
- X callsys WaitPort * Wait for Workbench startup message
- X lea pr_MsgPort(a3),a0 * Get our message port again
- X callsys GetMsg * Get startup message
- X move.l d0,WBenchMsg(a4) * Save pointer to it
- X move.l d0,-(sp) * Save it as argv
- X moveq #0,d0 * And push argc of 0 to indicate WB
- X move.l d0,-(sp) *
- X bra cont * Skip to init BSS and start prog
- X
- X*------ find command name:
- Xgetcom:
- X move.l pr_CLI(a3),a0
- X add.l a0,a0
- X add.l a0,a0
- X move.l cli_CommandName(a0),a1
- X add.l a1,a1
- X add.l a1,a1
- X
- X*------ collect parameters:
- X move.l d2,d0 * get command line length
- X moveq.l #0,d1
- X move.b (a1)+,d1
- X move.l a1,_ProgramName(A4)
- X add.l d1,d0 * add length of command name
- X addq.l #1,d0 * allow for space after command
- X
- X clr.w -(A7) * set null terminator for command line
- X addq.l #1,D0 * force to even number of bytes
- X andi.w #$fffe,D0 * (round up)
- X sub.l D0,A7 * make room on stack for command line
- X subq.l #2,D0
- X clr.w 0(A7,D0)
- X
- X*------ copy command line onto stack
- X move.l d2,d0 * get command line length
- X subq.l #1,d0
- X add.l d1,d2
- X
- Xcopy_line:
- X move.b 0(A2,D0.W),0(A7,D2.W) * copy command line to stack
- X subq.l #1,d2
- X dbf d0,copy_line
- X move.l d2,d0 * save offset to argv[1] - 1
- X clr.b 0(a7,d2.w) * Insert command name terminator
- X subq.l #1,d2
- X
- Xcopy_cmd:
- X move.b 0(a1,d2.w),0(a7,d2.w) * copy command name to stack
- X dbf d2,copy_cmd
- X lea 1(a7,d0.w),a1 * get pointer to start of arguments
- X move.l a7,a2 * get pointer for argv[0]
- X
- X sub.l #(MAXARGS*4),a7 * Reserve space for argv[]
- X move.l a7,a3 * Save ptr to base of argv (&argv[0])
- X move.l a2,(a7) * Setup argv[0] to point to cmd line
- X lea 4(a7),a2 * Init base into array at argv[1]
- X moveq #1,d2 * Initialise argc
- X
- X*
- X* From here on down, A1 is pointer into command line
- X*
- Xbuild_argv:
- X bsr.s getnext * Read next character from line
- X bcs.s doquote * If quote, handle
- X beq.s build_argv * If white space, skip over it
- X
- X lea -1(a1),a0 * Get address of this parameter
- X bsr.s bumpargv * Store it to argv[] array
- Xbuild_2:
- X bsr.s getnext * Get next character
- X bne.s build_2 * If not white space, keep looking
- X clr.b -1(a1) * Zero-terminate current argument
- X bra.s build_argv * And go back to get next argument
- X
- Xdoquote:
- X move.l a1,a0 * Get pointer to this argument
- X bsr.s bumpargv * Output it to argv[]
- Xquote_2:
- X bsr.s getnext * Get next character
- X bcc.s quote_2 * If not quote, keep looking
- X clr.b -1(a1) * Zero-terminate current argument
- Xquote_3:
- X bsr.s getnext * Get next character
- X bne.s quote_3 * Skip until space reached
- X beq.s build_argv * Go back and read next argument
- X
- Xbumpargv:
- X move.l a0,(a2)+ * Output ptr to current argument
- X addq #1,d2 * Increment argc
- X cmpi #MAXARGS,d2 * Used up all our arguments yet?
- X bls.s qrts * If not, then return
- X moveq #110,d0 * Else set return code
- X bra.s exit2 * And exit
- X
- X*
- X* Reads next character from command line. If zero, never returns, but
- X* drops into call to main. Else, returns, with C=1 if character is quote,
- X* Z=1 if character is white space.
- X*
- Xgetnext:
- X move.b (a1)+,d0 * Get character from command line
- X beq.s get_2 * Exit if end of line
- X cmp.b #34,d0 * Check if quote
- X beq.s isquote *
- X cmp.b #32,d0 * Check if space
- X beq.s isspace *
- X cmp.b #9,d0 * Or tab
- X beq.s isspace *
- X cmp.b #10,d0 * Or end of line
- Xisspace:
- X andi #$1E,ccr * Clear carry flag, retaining Z
- Xqrts rts
- X
- Xisquote:
- X ori #1,ccr * Set carry flag
- X andi #$FB,ccr * Clear zero flag
- X rts * And return
- X
- Xget_2:
- X move.l a3,-(a7) * Push argv onto stack
- X move.l d2,-(a7) * Push argc onto stack
- X
- Xcont:
- X lea _BSSBAS,a3 * get base of BSS
- X moveq #0,d1
- X move.l #_BSSLEN,d0 * get length of BSS in longwords
- X bra.s clr_lp * and clear for length given
- Xclr_bss move.l d1,(a3)+
- Xclr_lp dbf d0,clr_bss
- X
- Xdomain:
- X jsr main(PC) * Call main(argc,argv)
- X moveq.l #0,d0 * Set successful status
- X bra.s exit2
- X
- XNoDos:
- X moveq.l #100,d0 * Exit thread if no dos.library
- X bra.s exit2 *
- X
- Xexit:
- X_exit:
- XXCEXIT:
- X move.l 4(SP),d0 * Extract return code
- Xexit2:
- X move.l d0,-(a7)
- X move.l AbsExecBase.W,a6
- X move.l DOSBase(A4),a1
- X callsys CloseLibrary * Close Dos library
- X
- X*------ this rts sends us back to DOS:
- X tst.l WBenchMsg(a4) * Did we run from Workbench
- X beq.s ExitToDOS * If not, skip WB cleanup
- X move.l SysBase(A4),a6 *
- X callsys Forbid * Stop Workbench unloading us too soon
- X move.l WBenchMsg(a4),a1 *
- X callsys ReplyMsg * Return our startup msg
- X
- XExitToDOS:
- X move.l (A7)+,D0
- X movea.l _StackPtr(a4),SP * Restore stack ptr
- X movem.l (a7)+,d1-d6/a0-a6
- X rts
- X
- X*-----------------------------------------------------------------------
- X* Global definitions
- X*
- X csect __MERGED,1,,2,2
- X
- X xdef NULL,SysBase,LoadAddress,DOSBase
- X xdef _oserr,_OSERR,_ONBREAK
- X xdef _ProgramName,_StackPtr,_base,WBenchMsg
- X
- XNULL dc.l 0
- X_base dc.l 0
- X_oserr equ *
- X_OSERR dc.l 0
- X_ONBREAK dc.l 0
- XSysBase dc.l 0
- XLoadAddress dc.l 0
- X_StackPtr dc.l 0
- XDOSBase dc.l 0
- X_ProgramName dc.l 0
- XWBenchMsg dc.l 0
- XDOSName dc.b 'dos.library',0
- X
- X END
- END_OF_FILE
- if test 7425 -ne `wc -c <'src/small.a'`; then
- echo shar: \"'src/small.a'\" unpacked with wrong size!
- fi
- # end of 'src/small.a'
- fi
- if test -f 'src/system.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/system.h'\"
- else
- echo shar: Extracting \"'src/system.h'\" \(356 characters\)
- sed "s/^X//" >'src/system.h' <<'END_OF_FILE'
- X#include <exec/types.h>
- X#include <exec/execbase.h>
- X#include <libraries/dos.h>
- X#include <libraries/dosextens.h>
- X#include <intuition/intuition.h>
- X#include <workbench/startup.h>
- X#include <workbench/workbench.h>
- X#include <proto/exec.h>
- X#include <proto/dos.h>
- X#include <proto/graphics.h>
- X#include <proto/intuition.h>
- X#include <proto/icon.h>
- X#include <string.h>
- END_OF_FILE
- if test 356 -ne `wc -c <'src/system.h'`; then
- echo shar: \"'src/system.h'\" unpacked with wrong size!
- fi
- # end of 'src/system.h'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.misc.
-